/*
 *    Copyright (c) 2018-2025, proj All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the proj developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: proj
 */

package com.ykht.proj.coupon.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ykht.proj.activity.constant.CardConstant;
import com.ykht.proj.activity.dto.EntExportRedeemCode;
import com.ykht.proj.activity.vo.VOrderCardVo;
import com.ykht.proj.admin.api.entity.SysUser;
import com.ykht.proj.admin.api.feign.RemoteUserService;
import com.ykht.proj.common.core.util.R;
import com.ykht.proj.common.security.util.SecurityUtils;
import com.ykht.proj.coupon.dto.FxWithdrawalDetailsExport;
import com.ykht.proj.coupon.dto.FxWithdrawalExport;
import com.ykht.proj.coupon.service.FxWaiterExtService;
import com.ykht.proj.coupon.service.FxWithdrawalService;
import com.ykht.proj.coupon.vo.FxWithdrawalVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 提现记录表
 *
 * @author proj code generator
 * @date 2021-02-01 19:00:17
 */
@RestController
@AllArgsConstructor
@RequestMapping("/fxwithdrawal")
@Api(value = "fxwithdrawal", tags = "提现记录表管理")
@Slf4j
public class FxWithdrawalController {

	private final FxWithdrawalService fxWithdrawalService;
	/**
	 * 服务员 服务
	 */
	private final FxWaiterExtService fxWaiterExtService;
	/**
	 * 用户 服务 Api
	 */
	private final RemoteUserService remoteUserService;

	@ApiOperation(value = "分页查询", notes = "分页查询")
	@GetMapping("/page")
	@PreAuthorize("@pms.hasPermission('coupon_fxwithdrawal_view')")
	public R getCnCouponLogPage(Page page, FxWithdrawalVo fxWithdrawalVo) {
		return R.ok();
	}

	/**
	 * 提现记录 分页查询(服务员，门店 ，品牌，公司)
	 *
	 * @param page           分页对象
	 * @param fxWithdrawalVo
	 * @return
	 */
	@ApiOperation(value = "提现记录 分页查询(服务员，门店 ，品牌，公司)", notes = "提现记录 分页查询(服务员，门店 ，品牌，公司)")
	@GetMapping("/getWithdrawalListPage")
	@PreAuthorize("@pms.hasPermission('coupon_fxwithdrawal_view')")
	public R<IPage<FxWithdrawalVo>> getWithdrawalListPage(Page page, FxWithdrawalVo fxWithdrawalVo) {
		fxWithdrawalVo.setLoginRoleType(SecurityUtils.getUser().getUserType());
		fxWithdrawalVo.setLoginId(SecurityUtils.getSjId());
		IPage<FxWithdrawalVo> fxWithdrawalVoIPage = new Page<>();
		if (null != fxWithdrawalVo.getNickName() && !"".equals(fxWithdrawalVo.getNickName())) {
			List<SysUser> userList = remoteUserService.findByUserNameAndUserPhone(fxWithdrawalVo.getNickName());
			if (userList.size() > 0) {
				List<Long> userIds = userList.stream().map(itme -> Long.valueOf(itme.getUserId())).collect(Collectors.toList());
				fxWithdrawalVo.setUserIds(userIds);
			} else {
				return R.ok(fxWithdrawalVoIPage);
			}
		}
		fxWithdrawalVoIPage = fxWithdrawalService.getWithdrawalListPage(page, fxWithdrawalVo);
		fxWithdrawalVoIPage.getRecords().stream().forEach(itme -> {
			itme.setSureWithdrawalMoney(itme.getCumulativeMoney().subtract(itme.getCumulativeWithdrawalMoney()));
		});
		// 判断是否查看的是 服务员， 并给服务员赋值 姓名 电话
		if (1 == fxWithdrawalVo.getLookRoleType()) {
			List<FxWithdrawalVo> records = fxWithdrawalVoIPage.getRecords();
			if (records.size() > 0) {
				List<Long> ids = records.stream().map(itme -> Long.valueOf(itme.getLoginId())).collect(Collectors.toList());
				List<SysUser> userList = remoteUserService.userByIds(ids);
				records.stream().forEach(itme -> {
					userList.stream().forEach(user -> {
						if (itme.getLoginId().equals(Long.valueOf(user.getUserId()))) {
							itme.setUsername(user.getUsername());
							itme.setNickName(user.getNickName());
							itme.setUserPhone(user.getPhone());
						}
					});
				});
				fxWithdrawalVoIPage.setRecords(records);
			}
		}
		return R.ok(fxWithdrawalVoIPage);
	}


	/**
	 * 导出提现记录(服务员，门店 ，品牌，公司) excel
	 * @param fxWithdrawalVo 提现记录
	 * @return
	 */
	@ApiOperation(value = "导出提现记录(服务员，门店 ，品牌，公司) excel", notes = "导出提现记录(服务员，门店 ，品牌，公司) excel")
	@GetMapping("/getWithdrawalExportRedeemCode" )
	public void getWithdrawalExportRedeemCode(FxWithdrawalVo fxWithdrawalVo) {
		log.info("->获取要导出提现记录(服务员，门店 ，品牌，公司) 的数据", fxWithdrawalVo);
		fxWithdrawalVo.setLoginRoleType(SecurityUtils.getUser().getUserType());
		fxWithdrawalVo.setLoginId(SecurityUtils.getSjId());
		IPage<FxWithdrawalVo> fxWithdrawalVoIPage = new Page<>();
		if (null != fxWithdrawalVo.getNickName() && !"".equals(fxWithdrawalVo.getNickName())) {
			List<SysUser> userList = remoteUserService.findByUserNameAndUserPhone(fxWithdrawalVo.getNickName());
			if (null != userList && userList.size() > 0) {
				List<Long> userIds = userList.stream().map(itme -> Long.valueOf(itme.getUserId())).collect(Collectors.toList());
				fxWithdrawalVo.setUserIds(userIds);
				fxWithdrawalVoIPage = fxWithdrawalService.getWithdrawalListPage(new Page().setSize(9999), fxWithdrawalVo);
			}
		} else {
			fxWithdrawalVoIPage = fxWithdrawalService.getWithdrawalListPage(new Page().setSize(9999), fxWithdrawalVo);
		}
		// 判断是否查看的是 服务员， 并给服务员赋值 姓名 电话
		if (1 == fxWithdrawalVo.getLookRoleType()) {
			List<FxWithdrawalVo> records = fxWithdrawalVoIPage.getRecords();
			if (records.size() > 0) {
				List<Long> ids = records.stream().map(itme -> Long.valueOf(itme.getLoginId())).collect(Collectors.toList());
				List<SysUser> userList = remoteUserService.userByIds(ids);
				records.stream().forEach(itme -> {
					userList.stream().forEach(user -> {
						if (itme.getLoginId().equals(Long.valueOf(user.getUserId()))) {
							itme.setUsername(user.getUsername());
							itme.setNickName(user.getNickName());
							itme.setUserPhone(user.getPhone());
						}
					});
				});
				fxWithdrawalVoIPage.setRecords(records);
			}
		}
		List<FxWithdrawalVo> dtoList = fxWithdrawalVoIPage.getRecords();
		log.info("->开始导出提现记录(服务员，门店 ，品牌，公司) excel", dtoList);
		List<FxWithdrawalExport> bean = new ArrayList<>();
		// 日期转换
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		dtoList.stream().forEach(itme -> {
			itme.setWithdrawalTypeShow(itme.getWithdrawalType().equals(1L) ? "微信提现" :
					itme.getWithdrawalType().equals(2L) ? "支付宝" : "银行卡");
			itme.setWithdrawalDateShow(dateTimeFormatter.format(itme.getCreateTime()));
			bean.add(BeanUtil.toBean(itme, FxWithdrawalExport.class));
		});
		ExcelWriter writer = null;
		ServletOutputStream out = null;
		HttpServletResponse response = null;
		try {
			writer = ExcelUtil.getWriter(true);
			response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
			//自定义标题名
			writer.addHeaderAlias("orderNumber", "订单编号");
			writer.addHeaderAlias("wxOrder", "微信交易单号");
			writer.addHeaderAlias("withdrawalDateShow", "提现时间");
			writer.addHeaderAlias("waiterId", "ID（服务员）");
			writer.addHeaderAlias("nickName", "用户名（服务员）");
			writer.addHeaderAlias("balance", "可提现余额（元）");
			writer.addHeaderAlias("money", "提现金额（元）");
			writer.addHeaderAlias("withdrawalTypeShow", "提现方式");

			// 一次性写出内容，使用默认样式，强制输出标题
			writer.write(bean, true);
			response.setContentType("application/vnd.ms-excel;charset=utf-8");
			//这里容易乱码 处理
			String name = "提现记录";
			name = URLEncoder.encode(name, "UTF-8");
			response.setHeader("Content-Disposition", "attachment;filename=" + name + ".xls");
			out = response.getOutputStream();
			writer.flush(out, true);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭writer
			writer.close();
		}
		//关闭输出Servlet流
		IoUtil.close(out);
	}



	/**
	 * 提现记录详情 的统计
	 *
	 * @param fxWithdrawalVo
	 * @return
	 */
	@ApiOperation(value = " 提现记录详情 的统计", notes = " 提现记录详情 的统计")
	@GetMapping("/getWithdrawalDetailsCount")
	public R<FxWithdrawalVo> getWithdrawalDetailsCount(FxWithdrawalVo fxWithdrawalVo) {
		fxWithdrawalVo.setLoginRoleType(SecurityUtils.getUser().getUserType());
		FxWithdrawalVo fxWithdrawalVoIPage = new FxWithdrawalVo();
		if (null != fxWithdrawalVo.getUsername()) {
			List<SysUser> userList = remoteUserService.findByUserName(fxWithdrawalVo.getUsername());
			if (userList.size() > 0) {
				List<Long> userIds = userList.stream().map(itme -> Long.valueOf(itme.getUserId())).collect(Collectors.toList());
				fxWithdrawalVo.setUserIds(userIds);
			} else {
				return R.ok(fxWithdrawalVoIPage);
			}
		}
		fxWithdrawalVoIPage = fxWithdrawalService.getWithdrawalDetailsCount(fxWithdrawalVo);
		if (null == fxWithdrawalVoIPage) {
			fxWithdrawalVoIPage = new FxWithdrawalVo();
		}
		fxWithdrawalVoIPage.setSureWithdrawalMoney(fxWithdrawalVoIPage.getCumulativeMoney().subtract(fxWithdrawalVoIPage.getCumulativeWithdrawalMoney()));
		return R.ok(fxWithdrawalVoIPage);
	}


	/**
	 * 提现记录详情列表分页
	 *
	 * @param fxWithdrawalVo
	 * @return
	 */
	@ApiOperation(value = "提现记录详情列表分页", notes = "提现记录详情列表分页")
	@GetMapping("/getWithdrawalDetailsListPage")
	public R<IPage<FxWithdrawalVo>> getWithdrawalDetailsListPage(Page page, FxWithdrawalVo fxWithdrawalVo) {
		fxWithdrawalVo.setLoginRoleType(SecurityUtils.getUser().getUserType());
		IPage<FxWithdrawalVo> detailsListPage = new Page<>();
		if (null != fxWithdrawalVo.getNickName() && !"".equals(fxWithdrawalVo.getNickName())) {
			List<SysUser> userList = remoteUserService.findByNickName(fxWithdrawalVo.getNickName());
			if (userList.size() > 0) {
				List<Long> userIds = userList.stream().map(itme -> Long.valueOf(itme.getUserId())).collect(Collectors.toList());
				fxWithdrawalVo.setUserIds(userIds);
			} else {
				return R.ok(detailsListPage);
			}
		}
		detailsListPage = fxWithdrawalService.getWithdrawalDetailsListPage(page, fxWithdrawalVo);
		List<FxWithdrawalVo> records = detailsListPage.getRecords();
		if (records.size() > 0) {
			List<Long> ids = records.stream().map(itme -> Long.valueOf(itme.getLoginId())).collect(Collectors.toList());
			List<SysUser> userList = remoteUserService.userByIds(ids);
			records.stream().forEach(itme -> {
				userList.stream().forEach(user -> {
					if (itme.getLoginId().equals(Long.valueOf(user.getUserId()))) {
						itme.setUsername(user.getUsername());
						itme.setNickName(user.getNickName());
						itme.setUserPhone(user.getPhone());
					}
				});
			});
			detailsListPage.setRecords(records);
		}
		return R.ok(detailsListPage);
	}

	/**
	 * 导出提现记录详情列表分页 excel
	 * @param fxWithdrawalVo 提现记录
	 * @return
	 */
	@ApiOperation(value = "导出提现记录详情列表分页 excel", notes = "导出提现记录详情列表分页 excel")
	@GetMapping("/getWithdrawalDetailsListExport" )
	public void getWithdrawalDetailsListExport(FxWithdrawalVo fxWithdrawalVo) {
		log.info("->获取要导出提现记录详情列表 的数据", fxWithdrawalVo);
		fxWithdrawalVo.setLoginRoleType(SecurityUtils.getUser().getUserType());
		IPage<FxWithdrawalVo> detailsListPage = new Page<>();
		if (null != fxWithdrawalVo.getNickName() && !"".equals(fxWithdrawalVo.getNickName())) {
			List<SysUser> userList = remoteUserService.findByNickName(fxWithdrawalVo.getNickName());
			if (userList.size() > 0) {
				List<Long> userIds = userList.stream().map(itme -> Long.valueOf(itme.getUserId())).collect(Collectors.toList());
				fxWithdrawalVo.setUserIds(userIds);
				detailsListPage = fxWithdrawalService.getWithdrawalDetailsListPage(new Page().setSize(9999), fxWithdrawalVo);
			}
		} else {
			detailsListPage = fxWithdrawalService.getWithdrawalDetailsListPage(new Page().setSize(9999), fxWithdrawalVo);
		}

		List<FxWithdrawalVo> records = detailsListPage.getRecords();
		if (records.size() > 0) {
			List<Long> ids = records.stream().map(itme -> Long.valueOf(itme.getLoginId())).collect(Collectors.toList());
			List<SysUser> userList = remoteUserService.userByIds(ids);
			records.stream().forEach(itme -> {
				userList.stream().forEach(user -> {
					if (itme.getLoginId().equals(Long.valueOf(user.getUserId()))) {
						itme.setUsername(user.getUsername());
						itme.setNickName(user.getNickName());
						itme.setUserPhone(user.getPhone());
					}
				});
			});
			detailsListPage.setRecords(records);
		}
		List<FxWithdrawalVo> dtoList = detailsListPage.getRecords();
		log.info("->开始导出提现记录详情列表分页excel", dtoList);
		List<FxWithdrawalDetailsExport> bean = new ArrayList<>();
		// 日期转换
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		dtoList.stream().forEach(itme -> {
			itme.setWithdrawalTypeShow(itme.getWithdrawalType().equals(1L) ? "微信提现" :
					itme.getWithdrawalType().equals(2L) ? "支付宝" : "银行卡");
			bean.add(BeanUtil.toBean(itme, FxWithdrawalDetailsExport.class));
		});
		ExcelWriter writer = null;
		ServletOutputStream out = null;
		HttpServletResponse response = null;
		try {
			writer = ExcelUtil.getWriter(true);
			response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
			//自定义标题名
			writer.addHeaderAlias("brandId", "品牌ID");
			writer.addHeaderAlias("brandName", "品牌名称");
			writer.addHeaderAlias("shopId", "门店ID");
			writer.addHeaderAlias("shopName", "门店名称");
			writer.addHeaderAlias("nickName", "用户名（服务员）");
			writer.addHeaderAlias("balance", "当前门店可提余额（元）");
			writer.addHeaderAlias("money", "提现金额（元）");
			writer.addHeaderAlias("withdrawalTypeShow", "提现方式");

			// 一次性写出内容，使用默认样式，强制输出标题
			writer.write(bean, true);
			response.setContentType("application/vnd.ms-excel;charset=utf-8");
			//这里容易乱码 处理
			String name = "提现记录详情明细";
			name = URLEncoder.encode(name, "UTF-8");
			response.setHeader("Content-Disposition", "attachment;filename=" + name + ".xls");
			out = response.getOutputStream();
			writer.flush(out, true);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭writer
			writer.close();
		}
		//关闭输出Servlet流
		IoUtil.close(out);
	}




	/**
	 * 提现记录详情列表分页 的 详情明细（提现流水）
	 *
	 * @param batchNumber
	 * @return
	 */
	@ApiOperation(value = "提现记录详情列表分页 的 详情明细（提现流水）", notes = "提现记录详情列表分页 的 详情明细（提现流水）")
	@GetMapping("/getWithdrawalDetailsInDetailsListPage")
	public R<IPage<FxWithdrawalVo>> getWithdrawalDetailsInDetailsListPage(Page page, String batchNumber) {
		IPage<FxWithdrawalVo> detailsListPage = fxWithdrawalService.getWithdrawalDetailsInDetailsListPage(page, batchNumber);
		List<FxWithdrawalVo> records = detailsListPage.getRecords();
		if (records.size() > 0) {
			List<Long> ids = records.stream().map(itme -> Long.valueOf(itme.getLoginId())).collect(Collectors.toList());
			List<SysUser> userList = remoteUserService.userByIds(ids);
			records.stream().forEach(itme -> {
				userList.stream().forEach(user -> {
					if (itme.getLoginId().equals(Long.valueOf(user.getUserId()))) {
						itme.setUsername(user.getUsername());
						itme.setNickName(user.getNickName());
					}
				});
			});
			detailsListPage.setRecords(records);
		}
		return R.ok(detailsListPage);
	}


}
